﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using GMap.NET;
using GMap.NET.WindowsForms;

namespace GMapClient
{
#if !PocketPC
    [Serializable]
    public class GMapMarkerPolygon : GMapMarker, ISerializable
#else
    public class GMapMarkerPolygon : GMapMarker
#endif
    {
        /// <summary>
        /// In Meters 用米数确定圆
        /// </summary>
        public int Radius;


        /// <summary>
        /// 用两个点确定圆
        /// </summary>
        //public PointLatLng mouseLastPoint;

        public bool isDrawed = false;
        public List<PointLatLng> drawingPoints = new List<PointLatLng>();


        public void addPoint(PointLatLng point)
        {
            drawingPoints.Add(point);
        }
        /// <summary>
        /// 是否用米数确定圆
        /// </summary>
        public bool IsMeter = true;


        /// <summary>
        /// specifies how the outline is painted
        /// </summary>
        [NonSerialized]
#if !PocketPC
        public Pen Stroke = new Pen(Color.FromArgb(155, Color.MidnightBlue));
#else
       public Pen Stroke = new Pen(Color.MidnightBlue);
#endif

        /// <summary>
        /// background color
        /// </summary>
        [NonSerialized]
#if !PocketPC
        public Brush Fill = new SolidBrush(Color.FromArgb(155, Color.AliceBlue));
#else
       public Brush Fill = new System.Drawing.SolidBrush(Color.AliceBlue);
#endif

        /// <summary>
        /// is filled
        /// </summary>
        public bool IsFilled = false;

        public GMapMarkerPolygon(PointLatLng p)
           : base(p)
        {
            Radius = 0; // 0m
            //mouseLastPoint = p;
            IsHitTestVisible = false; 
            //drawingPoints .Add(p);
        }

        public PointLatLng mouseLastPoint;

        public AreaStruct.AreaDrawType m_drawType = AreaStruct.AreaDrawType.DT_NONE;

        public string remark = "";
        public override void OnRender(Graphics g)
        {
            if (drawingPoints.Count == 0) return;
            if (isDrawed)
            {
                mouseLastPoint = drawingPoints[drawingPoints.Count - 1];
            }
            PointLatLng LastPoint = drawingPoints[drawingPoints.Count - 1];
            switch (m_drawType)
            {
                case AreaStruct.AreaDrawType.DT_CIRCLE:
                    #region DT_CIRCLE

                    if (isDrawed == false)
                    {
                        LastPoint = mouseLastPoint;
                    }
                    if (!IsMeter)
                        Radius = (int)Overlay.Control.MapProvider.Projection.GetDistance(Position, LastPoint) * 1000;

                    int R = (int)((Radius) / Overlay.Control.MapProvider.Projection.GetGroundResolution((int)Overlay.Control.Zoom, Position.Lat)) * 2;

                    if (IsFilled)
                    {
                        g.FillEllipse(Fill, new System.Drawing.Rectangle(LocalPosition.X - R / 2, LocalPosition.Y - R / 2, R, R));
                    }
                    g.DrawEllipse(Stroke, new System.Drawing.Rectangle(LocalPosition.X - R / 2, LocalPosition.Y - R / 2, R, R));
                    #endregion
                    break;
                case AreaStruct.AreaDrawType.DT_POLYGON:
                    #region DT_POLYGON
                    GPoint p0 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(drawingPoints[0], (int)Overlay.Control.Zoom);
                    GPoint p = new GPoint(LocalPosition.X, LocalPosition.Y);
                    for (int i = 0; i < drawingPoints.Count - 1; i++)
                    {
                        PointLatLng point1 = drawingPoints[i];
                        PointLatLng point2 = drawingPoints[i + 1];
                        GPoint p1 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(point1, (int)Overlay.Control.Zoom);
                        GPoint p2 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(point2, (int)Overlay.Control.Zoom);
                        g.DrawLine(Stroke, p1.X - p0.X + p.X, p1.Y - p0.Y + p.Y, p2.X - p0.X + p.X, p2.Y - p0.Y + p.Y);
                    }

                    if (isDrawed)
                    {
                        GPoint p2 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(mouseLastPoint, (int)Overlay.Control.Zoom);
                        g.DrawLine(Stroke, p.X, p.Y, p2.X - p0.X + p.X, p2.Y - p0.Y + p.Y);
                    }
                    else
                    {
                        GPoint p1 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(LastPoint, (int)Overlay.Control.Zoom);
                        GPoint p2 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(mouseLastPoint, (int)Overlay.Control.Zoom);
                        g.DrawLine(Stroke, p1.X - p0.X + p.X, p1.Y - p0.Y + p.Y, p2.X - p0.X + p.X, p2.Y - p0.Y + p.Y);
                    }
                    #endregion
                    break;
                case AreaStruct.AreaDrawType.DT_RECTANGLE:
                    #region DT_RECTANGLE
                    if (drawingPoints.Count >= 1)
                    {
                         p0 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(drawingPoints[0], (int)Overlay.Control.Zoom);
                        GPoint p1 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(drawingPoints[0], (int)Overlay.Control.Zoom);
                        GPoint p2 = Overlay.Control.MapProvider.Projection.FromLatLngToPixel(mouseLastPoint, (int)Overlay.Control.Zoom);
                        p = new GPoint(LocalPosition.X, LocalPosition.Y);
                        g.DrawLine(Stroke, p1.X - p0.X + p.X, p1.Y - p0.Y + p.Y, p2.X - p0.X + p.X, p1.Y - p0.Y + p.Y);
                        g.DrawLine(Stroke, p2.X - p0.X + p.X, p1.Y - p0.Y + p.Y, p2.X - p0.X + p.X, p2.Y - p0.Y + p.Y);
                        g.DrawLine(Stroke, p2.X - p0.X + p.X, p2.Y - p0.Y + p.Y, p1.X - p0.X + p.X, p2.Y - p0.Y + p.Y);
                        g.DrawLine(Stroke, p1.X - p0.X + p.X, p2.Y - p0.Y + p.Y, p1.X - p0.X + p.X, p1.Y - p0.Y + p.Y);
                        //g.DrawLine(Stroke, drawAreaPoints[0].X, drawAreaPoints[0].Y, mouseLastPoint.X, drawAreaPoints[0].Y);
                        //g.DrawLine(Stroke, mouseLastPoint.X, drawAreaPoints[0].Y, mouseLastPoint.X, mouseLastPoint.Y);
                        //g.DrawLine(Stroke, mouseLastPoint.X, mouseLastPoint.Y, drawAreaPoints[0].X, mouseLastPoint.Y);
                        //g.DrawLine(Stroke, drawAreaPoints[0].X, mouseLastPoint.Y, drawAreaPoints[0].X, drawAreaPoints[0].Y); 
                    }
                    #endregion
                    break;
            }
            if (!string.IsNullOrEmpty(remark))
            {
                g.DrawString(remark, new Font("宋体", 20), new SolidBrush(Color.Red),
                       new Point(LocalPosition.X, LocalPosition.Y));
            }
        }

        //public bool isDrawCom = true;
        public override void Dispose()
        {
            if (Stroke != null)
            {
                Stroke.Dispose();
                Stroke = null;
            }

            if (Fill != null)
            {
                Fill.Dispose();
                Fill = null;
            }

            base.Dispose();
        }

        public bool IsInside(PointLatLng p)
        {
            return (int)Overlay.Control.MapProvider.Projection.GetDistance(Position, p) * 1000 < Radius;
        }

#if !PocketPC

        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);

            // TODO: Radius, IsFilled
        }

        protected GMapMarkerPolygon(SerializationInfo info, StreamingContext context)
           : base(info, context)
        {
            // TODO: Radius, IsFilled
        }

        #endregion

#endif
    }
}
